package zx.lrn.notes.multi_threading;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 *
 * @ClassName: InheritableThreadLocalLrn
 * @Description: 可继承的ThreadLocal ThreadLocal没有继承功能，在当前线程新建的子线程是不会获得父线程的ThreadLocal信息，InheritableThreadLocal可以解决这个问题。
 *               InheritableThreadLocal能够实现继承的原因：在创建Thread时，会查看父线程的inheritableThreadLocals变量是否已经赋值， 若已赋值，
 *               子线程的inheritableThreadLocals会初始化，并copy父线程的inheritableThreadLocals中的值进来。从而实现了ThreadLocal的继承。
 * @Author: zhaoxuan
 * @Date: 2020/3/14 17:25
 **/
public class InheritableThreadLocalLrn {
    private static ExecutorService pool = Executors.newCachedThreadPool();

    // 使用可继承的ThreadLocal模拟记录调用链路
    public static void main(String[] args) {
        InheritableThreadLocal<Map<String, String>> inheritableThreadLocal = new InheritableThreadLocal<>();
        Map<String, String> chain = new HashMap<>();
        chain.put("stage1", "info1");
        chain.merge("nextStage", "2", (old, now) -> Integer.valueOf(old) + 1 + "");
        inheritableThreadLocal.set(chain);

        // 第二层调用
        pool.submit(() -> {
            Map<String, String> map = inheritableThreadLocal.get();
            map.put("stage" + map.get("nextStage"), "info" + map.get("nextStage"));
            map.merge("nextStage", "2", (old, now) -> Integer.valueOf(old) + 1 + "");
            // 第三层调用
            pool.submit(() -> {
                Map<String, String> finalMap = inheritableThreadLocal.get();
                finalMap.put("stage" + finalMap.get("nextStage"), "info" + finalMap.get("nextStage"));
                finalMap.merge("nextStage", "2", (old, now) -> Integer.valueOf(old) + 1 + "");
                System.out.println(finalMap);
            });
        });
    }
}
